package com.df.excel_export.excel;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.metadata.CellExtra;
import com.alibaba.excel.read.listener.ReadListener;
import com.df.excel_export.common.*;
import com.df.excel_export.excel_table.*;
import com.df.excel_export.project_config.ProjectConfig;
import lombok.extern.slf4j.Slf4j;

import java.io.File;
import java.util.*;

@Slf4j
public class ExcelTableHeaderListener implements ReadListener<Map<Integer, String>> {

    boolean canContinue = true;
    int rowNum = 0;
    int dataRowNum = 0;
    String tableType = Constant.TableType.Horizontal;
    int  parseType = 1;//1只解析表头
    ProjectConfig projectConfig;


    ExcelTableStructure structure = null;
    public ExcelTableHeaderListener(ExcelTableStructure structure,ProjectConfig projectConfig) {
        this.structure = structure;
        this.projectConfig = projectConfig;
    }

    @Override
    public void invoke(Map<Integer, String> rowData, AnalysisContext analysisContext) {
        String sheetName = analysisContext.readSheetHolder().getSheetName();
        if(structure.getTable()!=null && !structure.getTable().getSheetName().equals(sheetName)){
            return;
        }
        rowNum = analysisContext.readRowHolder().getRowIndex()+1;
        if(rowNum==1){
            handleRow1(rowData,analysisContext);
            return;
        }
        if(dataRowNum!=0 && rowNum>dataRowNum){
            return;
        }
        if(!ExportTask.canContinue()){
            return;
        }
        //表头其他处理
        if(structure.getTable().getType().equals(Constant.TableType.Horizontal)){
            handleHTableHead(rowData,analysisContext);
        }else {
            handleVTableHead(rowData);
        }
    }

    private void handleVTableHead(Map<Integer, String> rowData) {
        String s = rowData.get(0);
        if (s == null || s.isEmpty()) {
            return;
        }

        if (s.equals("header")) {
            VHeader vHeader = structure.getTable().getVHeader();
            //升序排
            int size = rowData.size();

            for (int i = 1; i < size; i++) {
                String s1 = rowData.get(i);
                if(s1.equals("key")){
                    vHeader.setKeyCol(i);
                    continue;
                }
                if(s1.equals("value")){
                    vHeader.setValueCol(i);
                    continue;
                }
                if(s1.equals("type")){
                    vHeader.setTypeCol(i);
                    continue;
                }
                if(s1.equals("desc")){
                    vHeader.setDescCol(i);
                    continue;
                }
                if(s1.equals("validators")){
                    vHeader.setValidatorsCol(i);
                    continue;
                }
            }


        }

    }

    private void handleHTableHead(Map<Integer, String> rowData, AnalysisContext analysisContext) {
        String s = rowData.get(0);
        if (s == null || s.isEmpty()) {
            return;
        }
        List<HHeader> hHeaders = structure.getTable().getHHeaders();
        Map<Integer, HHeader> hHeaders2 = structure.getTable().getHHeaders2();
        if (s.equals(Constant.HTableHeaderDefine.Header_FieldName)) {
            //升序排
            int size = rowData.size();

            for (int i = 1; i < size; i++) {
                HHeader hHeader = null;
                if(hHeaders.size()<i){
                    hHeader = new HHeader();
                    hHeaders.add(hHeader);
                    hHeaders2.put(i,hHeader);
                }else {
//                    hHeader = hHeaders.get(i-1);
                    hHeader = hHeaders2.get(i);
                }
                String enName = rowData.get(i);
                if(enName!=null && !enName.isBlank()){
                    hHeader.setEnName(rowData.get(i).trim());
                }
                hHeader.setCol(i);

            }
            return;
        }
        if (s.equals(Constant.HTableHeaderDefine.Header_FieldType)) {
            //升序排
            int size = rowData.size();
            for (int i = 1; i < size; i++) {
                HHeader hHeader = null;
                if(hHeaders.size()<i){
                    hHeader = new HHeader();
                    hHeaders.add(hHeader);
                    hHeaders2.put(i,hHeader);
                }else {
//                    hHeader = hHeaders.get(i-1);
                    hHeader = hHeaders2.get(i);
                }
                String fieldType = rowData.get(i);
                if(fieldType!=null && !fieldType.isBlank()){
                    hHeader.setType(fieldType.trim());
                }
                hHeader.setCol(i);
            }
            return;
        }
        if (s.equals(Constant.HTableHeaderDefine.Header_Group)) {
            //升序排
            int size = rowData.size();
            for (int i = 1; i < size; i++) {

                HHeader hHeader = null;
                if(hHeaders.size()<i){
                    hHeader = new HHeader();
                    hHeaders.add(hHeader);
                    hHeaders2.put(i,hHeader);
                }else {
//                    hHeader = hHeaders.get(i-1);
                    hHeader = hHeaders2.get(i);
                }
                String groupStr = rowData.get(i).trim();
                hHeader.setGroupStr(groupStr==null?"":groupStr);
                String[] split = groupStr.split(",");
                for (String group : split) {
                    hHeader.getGroups().add(group.trim());
                }
                hHeader.setCol(i);
            }
            return;
        }
        if (s.equals(Constant.HTableHeaderDefine.Header_Validators)) {
            //升序排
            int size = rowData.size();
            for (int i = 1; i < size; i++) {
                HHeader hHeader = null;
                if(hHeaders.size()<i){
                    hHeader = new HHeader();
                    hHeaders.add(hHeader);
                    hHeaders2.put(i,hHeader);
                }else {
//                    hHeader = hHeaders.get(i-1);
                    hHeader = hHeaders2.get(i);
                }
                String validatorsStr = rowData.get(i).trim();
                hHeader.setGroupStr(validatorsStr==null?"":validatorsStr);
                String[] split = validatorsStr.split(",");
                for (String validator : split) {
                    hHeader.getValidators().add(validator.trim());
                }
                hHeader.setCol(i);
            }
            return;
        }
        if (s.equals(Constant.HTableHeaderDefine.Header_FieldDesc)) {
            structure.getTable().setField_desc_row(rowNum);
            //升序排
            int size = rowData.size();
            for (int i = 1; i < size; i++) {
                HHeader hHeader = null;
                if(hHeaders.size()<i){
                    hHeader = new HHeader();
                    hHeaders.add(hHeader);
                    hHeaders2.put(i,hHeader);
                }else {
//                    hHeader = hHeaders.get(i-1);
                    hHeader = hHeaders2.get(i);
                }
                String zhName = rowData.get(i).trim();
                hHeader.setChName(zhName==null?"":zhName);
                hHeader.setCol(i);
            }
            return;
        }
    }

    @Override
    public void extra(CellExtra extra, AnalysisContext context) {
        if(!ExportTask.canContinue()){
            return;
        }
        if(structure.getTable().getType().equals(Constant.TableType.Horizontal)){
            if(structure.getTable().getField_desc_row().equals(0)){
                return;
            }
            int nowRow = extra.getRowIndex() + 1;
            if(!structure.getTable().getField_desc_row().equals(nowRow)){
                return;
            }
            String text = extra.getText();
            if(text==null|| text.isEmpty()){
                return;
            }
            Integer columnIndex = extra.getColumnIndex();
            HHeader hHeader1 = structure.getTable().getHHeaders2().get(columnIndex);
            if(hHeader1==null){
                return;
            }
            hHeader1.setCommont(text);
//            for (HHeader hHeader : structure.getTable().getHHeaders()) {
//                if(hHeader.getCol().equals(extra.getColumnIndex())){
//                    hHeader.setCommont(text);
//                }
//            }
        }
    }

    public String errorCellMsg(String filePath, String sheetName, int rowNum, int colNum) {
        return "  excel文件：" + filePath + "; sheet名：" + sheetName + " 行号：" + rowNum + " 列号：" + colNum;
    }

    private void handleRow1(Map<Integer, String> rowData, AnalysisContext analysisContext) {
        File exceFile = analysisContext.readWorkbookHolder().getFile();
        String n = analysisContext.readSheetHolder().getSheetName();
        if(rowData.size()<2){
            ExportTask.logger.error("配置表第一行未置数据起始行或表格名！解析失败。文件名："+exceFile.getName()+"  表格名："+n);
            ExportTask.nowTask.interrupt();
            return;
        }

        String absolutePath = exceFile.getAbsolutePath();
        ExcelTableMeta meta = new ExcelTableMeta();
        ExcelSheet sheet = new ExcelSheet();
        structure.setMeta(meta);
        structure.setTable(sheet);

        //meta信息填充
        String name = exceFile.getName();
        int index = name.lastIndexOf(".");
        name = name.substring(0,index);
        meta.setFileName(name);
        meta.setFileNameWithExtension(exceFile.getName());
        meta.setFilePath(absolutePath);
        meta.setLastModifyTime(exceFile.lastModified());

        //sheet第一行相关数据填充
        String sheetName = analysisContext.readSheetHolder().getSheetName();
        sheet.setSheetName(sheetName);

        int prefixLen = projectConfig.getTable_prefix().length();
        int suffixLen = projectConfig.getTable_suffix().length();
        String tableName = sheetName.substring(prefixLen);
        tableName = tableName.substring(0, tableName.length() - suffixLen);
        sheet.setTableName(tableName);


        //数据起始行
        String dataRowNumStr = rowData.get(0);
        try {
            dataRowNum = Integer.parseInt(dataRowNumStr);

        } catch (Exception e) {
            ExportTask.nowTask.interrupt();
            ExportTask.logger.error("数据起始行解析失败:" + errorCellMsg(absolutePath, sheetName, rowNum, 0));
            return;
        }
        sheet.setStartRow(dataRowNum);
        //表中文名
        sheet.setTableChName(rowData.get(1));
        //表类型
        String tableTypeStr = rowData.get(2);
        tableTypeStr=tableTypeStr==null?"h":tableTypeStr;
        if(tableTypeStr.toLowerCase().equals(Constant.TableType.Horizontal)){
            sheet.setType(Constant.TableType.Horizontal);
        }else if(tableTypeStr.toLowerCase().equals(Constant.TableType.Vertical)){
            sheet.setType(Constant.TableType.Vertical);
        }else {
            sheet.setType(Constant.TableType.Horizontal);
            ExportTask.logger.warn("未知的表类型："+tableTypeStr+" 使用默认值h;  目前只支持横表："+Constant.TableType.Horizontal+" 和竖表："+Constant.TableType.Vertical+" 文件名："+meta.getFileNameWithExtension()+"  sheet名："+sheet.getSheetName());
        }
        if(sheet.getType().equals(Constant.TableType.Horizontal)){
            if (dataRowNum < 6) {
                ExportTask.logger.error("数据起始行配置错误，不能小于6:" + errorCellMsg(absolutePath, sheetName, rowNum, 0));
                ExportTask.nowTask.interrupt();
                return;
            }
        }else {
            structure.getTable().setVHeader(new VHeader());
        }
        //分表需要
//        String spliteTableNumStr = rowData.get(3);
//        int spliteTableNum = 0;
//        try {
//            spliteTableNum = Integer.parseInt(spliteTableNumStr);
//        } catch (Exception e) {
//            if(!spliteTableNumStr.isEmpty()){
//                canContinue = false;
//                ExcelTools.addErrorMsg("分表需要解析错误："+errorCellMsg(absolutePath, sheetName, rowNum, 3));
//                return;
//            }
//        }
//        excelTable.setSpliteTableNum(spliteTableNum);
//        excelTable.setTableName();
        //其他
        int size = rowData.size();
        for (int i = 0; i < size; i++) {
            if(rowData.get(i)!=null){
                sheet.getAllParams().add(rowData.get(i));
            }
        }

    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        if(!ExportTask.canContinue()){
            return;
        }
        ExcelSheet table = structure.getTable();
        if(table.getType().equals(Constant.TableType.Horizontal)){
            Iterator<HHeader> iterator = table.getHHeaders().iterator();
            while (iterator.hasNext()){
                HHeader next = iterator.next();
                if(next.getEnName()==null || next.getEnName().isBlank()){
                    iterator.remove();
                    structure.getTable().getHHeaders2().remove(next.getCol());
                    continue;
                }
                if(next.getType()==null || next.getType().isBlank()){
                    iterator.remove();
                    structure.getTable().getHHeaders2().remove(next.getCol());
                }
            }
        } else if(table.getType().equals(Constant.TableType.Vertical)){
            //检查列名
            VHeader vHeader = table.getVHeader();
            if(vHeader.getKeyCol()==null){
                ExportTask.nowTask.interrupt();
                ExportTask.logger.error( "  excel文件：" + structure.getMeta().getFilePath() + "; sheet名：" + structure.getTable().getSheetName() + " 竖表缺失key列");
                return;
            }
            if(vHeader.getValueCol()==null){
                ExportTask.nowTask.interrupt();
                ExportTask.logger.error( "  excel文件：" + structure.getMeta().getFilePath() + "; sheet名：" + structure.getTable().getSheetName() + " 竖表缺失value列");
                return;
            }
            if(vHeader.getTypeCol()==null){
                ExportTask.nowTask.interrupt();
                ExportTask.logger.error( "  excel文件：" + structure.getMeta().getFilePath() + "; sheet名：" + structure.getTable().getSheetName() + " 竖表缺失type列");
                return;
            }

        }
        structure.setParserDone(true);
    }
}
